package com.turing.post.report.impl;

import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.TextMessage;
import javax.naming.InitialContext;

import weblogic.javaee.TransactionTimeoutSeconds;

import com.turing.post.antimoney.util.AlarmInfoDao;
import com.turing.post.antimoney.util.AlarmInfoDetailDao;
import com.turing.post.antimoney.util.AlarmRule;
import com.turing.post.antimoney.util.AlarmRuleDao;
import com.turing.post.antimoney.util.AlarmRulesBusiness;
import com.turing.post.datasorting.util.InComeSortingBusiness;
import com.turing.post.organization.util.IssueBranch;
import com.turing.post.organization.util.IssueBranchDao;
import com.turing.post.organization.util.IssueCompany;
import com.turing.post.organization.util.IssueCompanyDao;
import com.turing.post.organization.util.Merchant;
import com.turing.post.organization.util.MerchantDao;
import com.turing.post.organization.util.SaleBranch;
import com.turing.post.organization.util.SaleBranchDao;
import com.turing.post.organization.util.SysBranchDao;
import com.turing.post.report.util.DaySettlementBusiness;
import com.turing.post.report.util.MchTradErrLogBusiness;
import com.turing.post.transaction.util.MchTradDetailDao;
import com.turing.post.util.PCPSUtil;

@MessageDriven(mappedName = DayOffImpl.DAYOFF_QUEUE_NAME)
@TransactionTimeoutSeconds(value = 3600)
public class DayOffImpl implements MessageListener {

	@EJB(mappedName = "report.impl.DaySettlementBusinessImpl")
	private DaySettlementBusiness daySettlementBusinessImpl;

	@EJB(mappedName = "organization.impl.IssueCompanyDaoImpl")
	private IssueCompanyDao issueCompanyDaoImpl;

	@EJB(mappedName = "organization.impl.MerchantDaoImpl")
	private MerchantDao merchantDaoImpl;

	@EJB(mappedName = "transaction.impl.MchTradDetailDaoImpl")
	private MchTradDetailDao mchTradDetailDaoImpl;

	@EJB(mappedName = "datasorting.impl.InComeSortingBusinessImpl")
	private InComeSortingBusiness inComeSortingBusinessImpl;

	@EJB(mappedName = "organization.impl.SysBranchDaoImpl")
	private SysBranchDao sysBranchDaoImpl;

	@EJB(mappedName = "organization.impl.SaleBranchDaoImpl")
	private SaleBranchDao saleBranchDaoImpl;

	@EJB(mappedName = "antimoney.impl.AlarmRuleDaoImpl")
	private AlarmRuleDao alarmRuleDaoImpl;

	@EJB(mappedName = "organization.impl.IssueBranchDaoImpl")
	private IssueBranchDao issueBranchDaoImpl;

	@EJB(mappedName = "report.impl.MchTradErrLogBusinessImpl")
	private MchTradErrLogBusiness mchTradErrLogBusinessImpl;

	@EJB(mappedName = "antimoney.impl.AlarmInfoDetailDaoImpl")
	private AlarmInfoDetailDao alarmInfoDetailDaoImpl;

	@EJB(mappedName = "antimoney.impl.AlarmInfoDaoImpl")
	private AlarmInfoDao alarmInfoDaoImpl;

	public static final String DAYOFF_QUEUE_NAME = "DayOffImplQueue";

	/**
	 * 开始日终
	 */
	public static final String DAYOFF_STEP_START = "00";

	/**
	 * 静默阶段
	 */
	public static final String DAYOFF_STEP_SLIENT = "01";

	/**
	 * 产生某发卡商某日某销售商下属销售机构的机构卡种类日结数据
	 */
	public static final String DAYOFF_STEP_AccSysBranchCardDaySettlement = "10";

	/**
	 * 产生某发卡商某日某销售商下属销售机构的日结数据
	 */
	public static final String DAYOFF_STEP_AccSysBranchDaySettlement = "11";

	/**
	 * 产生某发卡商某日卡种类日结数据
	 */
	public static final String DAYOFF_STEP_AccSysCardDaySettlement = "12";

	/**
	 * 产生某发卡商某日的日结数据
	 */
	public static final String DAYOFF_STEP_AccSysDaySettlement = "13";

	/**
	 * 产生某发卡商某日的销售机构资金日结数据
	 */
	public static final String DAYOFF_STEP_SaleCapitalDaySettlement = "20";

	/**
	 * 产生某发卡商某日的销售机构日结数据
	 */
	public static final String DAYOFF_STEP_BranchDaySett = "21";

	/**
	 * 产生某发卡商某日所有分支机构的卡库存日结数据
	 */
	public static final String DAYOFF_STEP_IssueCardStockDaySettlement = "30";

	/**
	 * 产生某发卡商某日某销售商下辖销售分支机构的卡库存日结数据
	 */
	public static final String DAYOFF_STEP_SaleCardStockDaySettlement = "31";

	/**
	 * 产生某发卡商某日机构的凭证库存日结数据
	 */
	public static final String DAYOFF_STEP_VoucherStockDaySettlement = "32";

	/**
	 * 产生某发卡商某日按商户的日结数据
	 */
	public static final String DAYOFF_STEP_MerchantDaySettlement = "40";

	/**
	 * 产生某发卡商某日某商户的按销售机构日结数据
	 */
	public static final String DAYOFF_STEP_IncomeDaySettlementByMerchantNo = "41";

	/**
	 * 产生某发卡商某日某商户按业务类型日结数据
	 */
	public static final String DAYOFF_STEP_MerchantBusinessDaySettlement = "42";

	/**
	 * 迁移某商户交易流水到历史表中
	 */
	public static final String DAYOFF_STEP_MigrateMchTradDetailToHistory = "43";

	/**
	 * 产生某发卡商某发卡机构激活、授信额度账务日结表
	 */
	public static final String DAYOFF_STEP_CreditDaySettlement = "44";

	/**
	 * 商户交易数据清分
	 */
	public static final String DAYOFF_STEP_MerchantIncomeSort = "50";

	/**
	 * 反洗钱预警规则
	 */
	public static final String DAYOFF_STEP_AntiMoney = "60";

	/**
	 * 复位销售机构轧帐状态
	 */
	public static final String DAYOFF_STEP_ResetSaleBranchDayOffStatus = "97";

	/**
	 * 复位发卡商业务单号顺序号
	 */
	public static final String DAYOFF_STEP_ResetBusinessOrderSeqNo = "98";

	/**
	 * 日终完成
	 */
	public static final String DAYOFF_STEP_COMPLETE = "99";

	public boolean switchDayOffStatus(String issueCompanyNo,
			String dayOffStatus, String dayOffRemark) {
		return daySettlementBusinessImpl.switchDayOffStatus(issueCompanyNo,
				null, dayOffStatus, dayOffRemark);
	}

	private boolean generateAccSysBranchCardDaySettlement(
			String issueCompanyNo, Date tranDate, String issueBranchNo) {
		try {
			daySettlementBusinessImpl.generateAccSysBranchCardDaySettlement(
					issueCompanyNo, tranDate, issueBranchNo);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateAccSysBranchDaySettlement(String issueCompanyNo,
			Date tranDate, String issueBranchNo) {
		try {
			daySettlementBusinessImpl.generateAccSysBranchDaySettlement(
					issueCompanyNo, tranDate, issueBranchNo);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateAccSysCardDaySettlement(String issueCompanyNo,
			Date tranDate) {
		try {
			daySettlementBusinessImpl.generateAccSysCardDaySettlement(
					issueCompanyNo, tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateAccSysDaySettlement(String issueCompanyNo,
			Date tranDate) {
		try {
			daySettlementBusinessImpl.generateAccSysDaySettlement(
					issueCompanyNo, tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateSaleCapitalDaySettlement(String issueCompanyNo,
			Date tranDate) {
		try {
			daySettlementBusinessImpl.generateSaleCapitalDaySettlement(
					issueCompanyNo, tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateIssueCardStockDaySettlement(String issueCompanyNo,
			Date tranDate) {
		try {
			daySettlementBusinessImpl.generateIssueCardStockDaySettlement(
					issueCompanyNo, tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateSaleCardStockDaySettlement(String issueCompanyNo,
			Date tranDate, String issueBranchNo) {
		try {
			daySettlementBusinessImpl.generateSaleCardStockDaySettlement(
					issueCompanyNo, tranDate, issueBranchNo);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateVoucherStockDaySettlement(String issueCompanyNo,
			Date tranDate) {
		try {
			daySettlementBusinessImpl.generateVoucherStockDaySettlement(
					issueCompanyNo, tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateSaleBranchDaySett(String issueCompanyNo,
			Date tranDate, String saleBranchNo) {
		try {
			daySettlementBusinessImpl.generateBranchDaySett(issueCompanyNo,
					tranDate, saleBranchNo, false);
			return true;
		} catch (Exception e) {
		}
		return false;
	}

	public boolean generateMerchantDaySettlement(String issueCompanyNo,
			Date tranDate) {
		try {
			daySettlementBusinessImpl.generateMerchantDaySettlement(
					issueCompanyNo, tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateCreditDaySettlement(String issueCompanyNo,
			Date tranDate) {
		try {
			daySettlementBusinessImpl.generateCreditDaySettlement(
					issueCompanyNo, tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateMerchantBusinessDaySettlement(String issueCompanyNo,
			Date tranDate) {
		try {
			daySettlementBusinessImpl.generateMerchantBusinessDaySettlement(
					issueCompanyNo, tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean generateIncomeDaySettlementByMerchantNo(
			String issueCompanyNo, Date tranDate, String merchantNo) {
		try {
			daySettlementBusinessImpl.generateIncomeDaySettlementByMerchantNo(
					issueCompanyNo, tranDate, merchantNo);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean migrateMchTradDetailToHistory(String merchantNo,
			Date tranDate) {
		try {
			mchTradDetailDaoImpl.migrateMchTradDetailToHistory(merchantNo,
					tranDate);
			return true;
		} catch (Exception e) {
		}

		return false;
	}

	public boolean inComeSort(String merchantNo, Date tranDate) {
		try {
			inComeSortingBusinessImpl.inComeSort(merchantNo, tranDate);
			return true;
		} catch (Exception e) {
			PCPSUtil.Log(e);
		}

		return false;
	}

	public boolean resetSysBranchSeqNoByIssueCompanyNo(String issueCompanyNo) {
		try {
			sysBranchDaoImpl
					.resetSysBranchSeqNoByIssueCompanyNo(issueCompanyNo);
			return true;
		} catch (Exception e) {
			PCPSUtil.Log(e);
		}

		return false;
	}

	public boolean resetSaleBranchDayOffStatus(String issueCompanyNo) {
		try {
			saleBranchDaoImpl.setDayOffStatus(issueCompanyNo, null,
					SaleBranch.Not_DayOff);
			return true;
		} catch (Exception e) {
			PCPSUtil.Log(e);
		}

		return false;
	}

	public boolean antiMoney(InitialContext ctx, String issueCompanyNo,
			Date tranDate, AlarmRule ar) {
		try {
			// 开始执行预警规则
			AlarmRulesBusiness arb = (AlarmRulesBusiness) ctx.lookup(ar
					.getJNDIName()
					+ "#" + AlarmRulesBusiness.class.getName());
			if (arb == null) {
				PCPSUtil.Log(String.format("查找预警规则[%s][%s]的实现[%s]失败!", ar
						.getAlarmRuleId().toString(), ar.getAlarmRuleDesc(), ar
						.getJNDIName()));
				return true;
			}
			arb.runAlarmRules(issueCompanyNo, tranDate, ar);
			return true;
		} catch (Exception e) {
			PCPSUtil.Log(e);
		}

		return true;
	}

	/**
	 * 真实的日终流程
	 * 
	 * @param ctx
	 *            上下文
	 * @param issueCompanyNo
	 *            发卡商号
	 */
	private void dayOff(InitialContext ctx, String issueCompanyNo) {
		// 取发卡商数据
		IssueCompany issueCompany = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(issueCompanyNo);
		if (issueCompany == null)
			return;

		// 取日终日期
		java.util.Calendar cal = java.util.Calendar.getInstance();
		cal.setTime(PCPSUtil.getZeroedHMS(issueCompany.getTranDate()));
		cal.add(java.util.Calendar.DAY_OF_MONTH, -1);

		Date tranDate = PCPSUtil.getZeroedHMS(cal.getTime());
		String s_tranDate = PCPSUtil.getStringYMDByDate(tranDate);

		cal.add(java.util.Calendar.DAY_OF_MONTH, -7);
		Date mig_tranDate = PCPSUtil.getZeroedHMS(cal.getTime());
		String s_mig_tranDate = PCPSUtil.getStringYMDByDate(mig_tranDate);

		String remark;

		// 取所有的发卡机构
		List<IssueBranch> scmplist = issueBranchDaoImpl
				.getAllIssueBranchByIssueCompanyNo(issueCompanyNo);

		// 取所有的商户
		List<Merchant> mchlist = merchantDaoImpl
				.getMerchantListByIssueCompanyNo(issueCompanyNo);

		// 取所有的销售机构
		List<SaleBranch> sbrchlist = saleBranchDaoImpl
				.getAllSaleBranchByIssueCompanyNo(issueCompanyNo);

		// step 01 -- 静默阶段 - 30秒
		remark = "静默阶段!";
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_SLIENT, remark);
		try {
			Thread.sleep(30000);
		} catch (Exception e) {
		}

		// step 10 -- 产生某发卡商某日某销售商下属销售机构的机构卡种类日结数据
		for (IssueBranch scmp : scmplist) {
			remark = String.format("产生[%s][%s][%s]下属销售机构的机构卡种类日结数据",
					issueCompanyNo, s_tranDate, scmp.getIssueBranchNo());
			PCPSUtil.Log(remark);
			switchDayOffStatus(issueCompanyNo,
					DAYOFF_STEP_AccSysBranchCardDaySettlement, remark);
			if (!generateAccSysBranchCardDaySettlement(issueCompanyNo,
					tranDate, scmp.getIssueBranchNo()))
				return;
		}

		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_AccSysBranchCardDaySettlement, "销售机构卡种类数据扎帐完成");

		// step 11 -- 产生某发卡商某日某销售商下属销售机构的日结数据
		for (IssueBranch scmp : scmplist) {
			remark = String.format("产生[%s][%s][%s]下属销售机构的日结数据", issueCompanyNo,
					s_tranDate, scmp.getIssueBranchNo());
			PCPSUtil.Log(remark);
			switchDayOffStatus(issueCompanyNo,
					DAYOFF_STEP_AccSysBranchDaySettlement, remark);
			if (!generateAccSysBranchDaySettlement(issueCompanyNo, tranDate,
					scmp.getIssueBranchNo()))
				return;
		}

		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_AccSysBranchDaySettlement, "销售机构数据扎帐完成");

		// step 12 -- 产生某发卡商某日卡种类日结数据
		remark = String.format("产生[%s][%s]卡种类日结数据", issueCompanyNo, s_tranDate);
		PCPSUtil.Log(remark);
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_AccSysCardDaySettlement,
				remark);
		if (!generateAccSysCardDaySettlement(issueCompanyNo, tranDate))
			return;

		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_AccSysCardDaySettlement,
				"卡种类日结数据扎帐完成");

		// step 13 -- 产生某发卡商某日的日结数据
		remark = String.format("产生[%s][%s]日结数据", issueCompanyNo, s_tranDate);
		PCPSUtil.Log(remark);
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_AccSysDaySettlement,
				remark);
		if (!generateAccSysDaySettlement(issueCompanyNo, tranDate))
			return;

		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_AccSysDaySettlement,
				"发卡商某日的日结数据扎帐完成");

		// step 20 -- 产生某发卡商某日的销售机构资金日结数据
		remark = String.format("产生[%s][%s]销售机构资金日结数据", issueCompanyNo,
				s_tranDate);
		PCPSUtil.Log(remark);
		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_SaleCapitalDaySettlement, remark);
		if (!generateSaleCapitalDaySettlement(issueCompanyNo, tranDate))
			return;

		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_SaleCapitalDaySettlement, "某发卡商某日的销售机构资金日结数据扎帐完成");

		// step 21 -- 产生某发卡商某日某销售分支机构的日结数据
		for (SaleBranch sbrch : sbrchlist) {
			remark = String.format("产生[%s][%s][%s]销售分支机构的日结数据", issueCompanyNo,
					s_tranDate, sbrch.getSaleBranchNo());
			PCPSUtil.Log(remark);
			switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_BranchDaySett,
					remark);
			if (!generateSaleBranchDaySett(issueCompanyNo, tranDate, sbrch
					.getSaleBranchNo()))
				return;
		}

		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_BranchDaySett,
				"发卡商分支机构的日结数据扎帐完成");

		// step 30 -- 产生某发卡商某日所有分支机构的卡库存日结数据
		remark = String.format("产生[%s][%s]所有分支机构的卡库存日结数据", issueCompanyNo,
				s_tranDate);
		PCPSUtil.Log(remark);
		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_IssueCardStockDaySettlement, remark);
		if (!generateIssueCardStockDaySettlement(issueCompanyNo, tranDate))
			return;

		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_IssueCardStockDaySettlement, "分支机构的卡库存日结数据扎帐完成");

		// step 31 -- 产生某发卡商某日某销售商下辖销售分支机构的卡库存日结数据
		for (IssueBranch scmp : scmplist) {
			remark = String.format("产生[%s][%s][%s]下辖销售分支机构的卡库存日结数据",
					issueCompanyNo, s_tranDate, scmp.getIssueBranchNo());
			PCPSUtil.Log(remark);
			switchDayOffStatus(issueCompanyNo,
					DAYOFF_STEP_SaleCardStockDaySettlement, remark);
			if (!generateSaleCardStockDaySettlement(issueCompanyNo, tranDate,
					scmp.getIssueBranchNo()))
				return;
		}

		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_SaleCardStockDaySettlement, "销售分支机构的卡库存日结数据扎帐完成");

		// step 32 -- 产生某发卡商某日机构的凭证库存日结数据
		remark = String.format("产生[%s][%s]下辖机构的凭证库存日结数据", issueCompanyNo,
				s_tranDate);
		PCPSUtil.Log(remark);
		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_VoucherStockDaySettlement, remark);
		if (!generateVoucherStockDaySettlement(issueCompanyNo, tranDate))
			return;
		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_VoucherStockDaySettlement, "凭证库存日结数据扎帐完成");

		// step 40 -- 产生某发卡商某日按商户的日结数据
		remark = String
				.format("产生[%s][%s]按商户的日结数据", issueCompanyNo, s_tranDate);
		PCPSUtil.Log(remark);
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_MerchantDaySettlement,
				remark);
		if (!generateMerchantDaySettlement(issueCompanyNo, tranDate))
			return;
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_MerchantDaySettlement,
				"商户的日结数据扎帐完成");

		// step 41 -- 产生某发卡商某日某商户的按销售机构日结数据
		for (Merchant mrch : mchlist) {
			remark = String.format("产生[%s][%s][%s]的按销售机构日结数据", issueCompanyNo,
					s_tranDate, mrch.getMerchantNo());
			PCPSUtil.Log(remark);
			switchDayOffStatus(issueCompanyNo,
					DAYOFF_STEP_IncomeDaySettlementByMerchantNo, remark);
			if (!generateIncomeDaySettlementByMerchantNo(issueCompanyNo,
					tranDate, mrch.getMerchantNo()))
				return;
		}

		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_IncomeDaySettlementByMerchantNo, "商户的按销售机构日结数据扎帐完成");

		// step 42 -- 产生某发卡商某日按商户及业务类型日结数据
		remark = String.format("产生[%s][%s]的按商户及业务类型日结数据", issueCompanyNo,
				s_tranDate);
		PCPSUtil.Log(remark);
		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_MerchantBusinessDaySettlement, remark);
		if (!generateMerchantBusinessDaySettlement(issueCompanyNo, tranDate))
			return;

		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_MerchantBusinessDaySettlement, "商户及业务类型日结数据扎帐完成");

		// step 43 -- 迁移某商户一周前的交易流水到历史表中
		for (Merchant mrch : mchlist) {
			remark = String.format("迁移[%s][%s]交易流水到历史表中", mrch.getMerchantNo(),
					s_mig_tranDate);
			PCPSUtil.Log(remark);
			switchDayOffStatus(issueCompanyNo,
					DAYOFF_STEP_MigrateMchTradDetailToHistory, remark);
			if (!migrateMchTradDetailToHistory(mrch.getMerchantNo(),
					mig_tranDate))
				return;
		}

		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_MigrateMchTradDetailToHistory, "迁移某商户一周前的交易流水完成");

		// step 44 -- 产生某发卡商某发卡机构激活、授信额度账务日结表
		remark = String.format("产生[%s][%s]激活、授信额度账务日结表", issueCompanyNo,
				s_tranDate);
		PCPSUtil.Log(remark);
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_CreditDaySettlement,
				remark);
		if (!generateCreditDaySettlement(issueCompanyNo, tranDate))
			return;
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_MerchantDaySettlement,
				"激活、授信额度账务日结完成");

		// step 50 -- 商户收益清分
		for (Merchant mrch : mchlist) {
			remark = String.format("清分[%s][%s]交易数据", mrch.getMerchantNo(),
					s_tranDate);
			PCPSUtil.Log(remark);
			switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_MerchantIncomeSort,
					remark);
			if (!inComeSort(mrch.getMerchantNo(), tranDate))
				return;
		}

		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_MerchantIncomeSort,
				"商户收益清分完成");

		// step 60 -- 执行所有的预警规则
		List<AlarmRule> arlist = alarmRuleDaoImpl
				.getAllAlarmRuleByIssueCompanyNo(issueCompanyNo);
		if (arlist != null) {
			// 1.清空某发卡商某日所有预警信息明细
			List<String> almInfoIds = alarmInfoDetailDaoImpl
					.getAlarmInfoIdFromDetailByTranDate(issueCompanyNo,
							tranDate);
			alarmInfoDetailDaoImpl.removeAlarmInfoDetailByTranDate(
					issueCompanyNo, tranDate);
			// 2.清空某发卡商某日所有预警信息
			if (null != almInfoIds && almInfoIds.size() > 0) {
				for (int i = 0; i < almInfoIds.size(); i++) {
					if (almInfoIds.get(i) != null) {
						alarmInfoDaoImpl.removeAlarmInfoByInfoId(almInfoIds
								.get(i));
					}
				}
			}

			for (AlarmRule ar : arlist) {
				remark = String.format("执行反洗钱预警规则[%s]", ar.getAlarmRuleDesc());
				PCPSUtil.Log(remark);
				switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_AntiMoney,
						remark);
				if (!antiMoney(ctx, issueCompanyNo, tranDate, ar))
					return;
			}
			switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_AntiMoney,
					"执行所有的预警规则完成");
		}

		// step 97 -- 复位销售机构轧帐状态
		remark = "复位销售机构轧帐状态";
		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_ResetSaleBranchDayOffStatus, remark);
		if (!resetSaleBranchDayOffStatus(issueCompanyNo))
			return;
		switchDayOffStatus(issueCompanyNo,
				DAYOFF_STEP_ResetSaleBranchDayOffStatus, "复位销售机构轧帐状态");

		// step 98 -- 复位发卡商业务单号顺序号
		remark = "复位发卡商业务单号顺序号";
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_ResetBusinessOrderSeqNo,
				remark);
		if (!resetSysBranchSeqNoByIssueCompanyNo(issueCompanyNo))
			return;
		switchDayOffStatus(issueCompanyNo, DAYOFF_STEP_ResetBusinessOrderSeqNo,
				"复位发卡商业务单号顺序号完成");

		// step 99 -- 日终完成
		remark = "日终正常完成!";
		daySettlementBusinessImpl.switchDayOffStatus(issueCompanyNo,
				IssueCompany.ISSUECOMPANY_NORMAL_TRANSACTION,
				DAYOFF_STEP_COMPLETE, remark);

		PCPSUtil.Log(remark);
	}

	/**
	 * 处理联机交易异常信息
	 * 
	 * @param om
	 * @throws Exception
	 */
	private void handleLogException(ObjectMessage om) throws Exception {
		Object obj = om.getObject();
		if (!(obj instanceof Object[]))
			return;
		Object[] obm = (Object[]) obj;
		if (obm.length != 3 || !PCPSUtil.compareObject(obm[0], "LOGEXCEPTION"))
			return;
		byte[] ibuf = (byte[]) obm[1];
		Exception ex = (Exception) obm[2];
		mchTradErrLogBusinessImpl.createMchTradErrLog(ibuf, ex);
	}

	public void onMessage(Message message) {
		if (message == null)
			return;
		try {
			if (message.getJMSRedelivered())
				return;
		} catch (JMSException e1) {
			return;
		}

		if (message instanceof ObjectMessage) {
			try {
				handleLogException((ObjectMessage) message);
			} catch (Exception e) {
			}
			return;
		}

		if (message instanceof TextMessage) {
			TextMessage tm = (TextMessage) message;
			try {
				String issueCompanyNo = tm.getText().trim();
				if (PCPSUtil.isEmpty(issueCompanyNo)
						|| issueCompanyNo.length() != 6)
					return;
				PCPSUtil.setDayOffLogEntry(issueCompanyNo);
				PCPSUtil.Log("begin DayOff: " + issueCompanyNo);
				InitialContext ctx = new InitialContext();
				// 开始日终
				dayOff(ctx, issueCompanyNo);
			} catch (Exception e) {
				PCPSUtil.Log("onMessage 异常 !");
				PCPSUtil.Log(e);
			}
		}
	}
}